package com.maddox.relax.camera.c2

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraDevice
import android.hardware.camera2.CameraManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
import android.os.Message
import android.util.Size
import android.view.TextureView
import android.widget.Toast
import androidx.annotation.MainThread
import androidx.core.app.ActivityCompat
import com.maddox.relax.R
import com.maddox.relax.databinding.ActivityCamera2PicBinding
import com.maddox.relax.permission.PermissionOnCallback
import com.maddox.relax.permission.PermissionX
import com.maddox.relax.util.LogUtil

/**
 * 基于Camera2的拍照页面
 */
class Camera2PicActivity : AppCompatActivity(), Handler.Callback {
    //要求摄像支持的等级
    private val REQUEST_SUPPORT_HARDWARE_LEVEL =
        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL
    private lateinit var bd: ActivityCamera2PicBinding

    //前置摄像头信息
    private var mFrontCameraId: String? = null
    private lateinit var mFrontCameraCharacteristics: CameraCharacteristics

    //后置摄像头信息
    private var mBackCameraId: String? = null
    private lateinit var mBackCameraCharacteristics: CameraCharacteristics

    //相机的消息线程
    private val cameraThread = HandlerThread("CameraThread").apply { start() }

    //相机的消息处理
    private val cameraHandler: Handler = Handler(cameraThread.looper, this)

    //当前相机
    private var cameraDevice: CameraDevice? = null


    companion object {
        //开启相机
        private const val MSG_OPEN_CAMERA: Int = 1
        //关闭相机
        private const val MSG_CLOSE_CAMERA: Int = 2
        //预览宽度
        private const val MAX_PREVIEW_WIDTH: Int = 1440
        //预览高度
        private const val MAX_PREVIEW_HEIGHT: Int = 1080
        //照片宽度
        private const val MAX_IMAGE_WIDTH: Int = 4032
        //照片高度
        private const val MAX_IMAGE_HEIGHT: Int = 3024

    }

    //1.获取相机管理器
    private val cameraManager: CameraManager by lazy {
        getSystemService(Context.CAMERA_SERVICE) as CameraManager
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bd = ActivityCamera2PicBinding.inflate(layoutInflater)
        setContentView(bd.root)
        initView()
    }

    private fun initView() {
        initPermission()
        //2.获取相机ID列表
        val cameraIdList = cameraManager.cameraIdList
        //3.根据相机id获取对应相机的详细信息
        for (cameraId in cameraIdList) {
            LogUtil.d("相机id:${cameraId}")
            val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId)
            //校验当前设备是否支持camera2
//            if (cameraCharacteristics.isHardWareLevelSupport(REQUEST_SUPPORT_HARDWARE_LEVEL)) {
            val lensFacing = cameraCharacteristics[CameraCharacteristics.LENS_FACING]
            when (lensFacing) {
                CameraCharacteristics.LENS_FACING_FRONT -> {
                    //前置摄像头
                    mFrontCameraId = cameraId
                    mFrontCameraCharacteristics = cameraCharacteristics
                }
                CameraCharacteristics.LENS_FACING_BACK -> {
                    //后置摄像头
                    mBackCameraId = cameraId
                    mBackCameraCharacteristics = cameraCharacteristics
                }
                CameraCharacteristics.LENS_FACING_EXTERNAL -> {

                }
            }
//            } else {
//                Toast.makeText(this, "当前设备不支持Camera2", Toast.LENGTH_SHORT).show()
//            }

        }
        //4.开启相机
        openCamera(mBackCameraId)
        //5.开启预览
        bd.cameraPreview.surfaceTextureListener = PreviewSurfaceTextureListener()

    }


    //获取合适的预览尺寸
    private fun getOptimalSize(cameraCharacteristics: CameraCharacteristics,clazz: Class<*>,maxWidth:Int,maxHeight:Int): Size? {
        val aspectRatio = maxWidth.toFloat()/maxHeight
        val streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
        val outputSizes = streamConfigurationMap?.getOutputSizes(SurfaceTexture::class.java)
        if (outputSizes!=null){
            outputSizes.forEach {
                if (it.width.toFloat()/it.height==aspectRatio&&it.height<=maxHeight&&it.width<=maxWidth){
                    return it
                }
            }
        }
        return null
    }

    //开启相机
    @MainThread
    private fun openCamera(cameraId: String?) {
        if (cameraId != null) {
            val openCameraMessage = OpenCameraMessage(cameraId, CameraStateCallback())
            cameraHandler.obtainMessage(MSG_OPEN_CAMERA, openCameraMessage).sendToTarget()

        }
    }

    //判断指定摄像头支持的camera2等级
    fun CameraCharacteristics.isHardWareLevelSupport(requiredLevel: Int): Boolean {
        val sortedLevels = intArrayOf(
            CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
            CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
            CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
            CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
        )
        //当前CameraCharacteristics的设备等级
        val deviceLevel = this[CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL]
        if (requiredLevel == deviceLevel) {
            return true
        }
        for (sortedLevel in sortedLevels) {
            if (requiredLevel == sortedLevel) {
                return true
            } else if (deviceLevel == sortedLevel) {
                return false
            }
        }
        return false
    }


    //
    private inner class PreviewSurfaceTextureListener : TextureView.SurfaceTextureListener{
        override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
            surface
        }

        override fun onSurfaceTextureSizeChanged(
            surface: SurfaceTexture?,
            width: Int,
            height: Int
        ) {

        }

        override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
            return false
        }

        override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {

        }

    }

    //开启相机的状态监听
    private inner class CameraStateCallback : CameraDevice.StateCallback() {
        override fun onOpened(camera: CameraDevice) {
            cameraDevice = camera
            Toast.makeText(this@Camera2PicActivity, "开启相机成功", Toast.LENGTH_SHORT).show()
        }

        override fun onDisconnected(camera: CameraDevice) {
            Toast.makeText(this@Camera2PicActivity, "关闭相机", Toast.LENGTH_SHORT).show()
        }

        override fun onError(camera: CameraDevice, error: Int) {
            Toast.makeText(this@Camera2PicActivity, "开启相机失败", Toast.LENGTH_SHORT).show()
            camera.close()
            cameraDevice = null
        }

    }

    private data class OpenCameraMessage(
        val cameraId: String,
        val cameraStateCallback: CameraStateCallback
    )

    //消息处理
    @SuppressLint("MissingPermission")
    override fun handleMessage(msg: Message): Boolean {
        when (msg.what) {
            MSG_OPEN_CAMERA -> {//开启相机
                val openCameraMessage = msg.obj as OpenCameraMessage
                val cameraId = openCameraMessage.cameraId
                val cameraStateCallback = openCameraMessage.cameraStateCallback
                cameraManager.openCamera(cameraId, cameraStateCallback, cameraHandler)
            }
            MSG_CLOSE_CAMERA -> {//关闭相机
                cameraDevice?.close()
                LogUtil.d("相机已关闭")
            }
        }
        return false
    }


    override fun onStop() {
        super.onStop()
        closeCamera()
    }

    private fun closeCamera() {
        cameraHandler.obtainMessage(MSG_CLOSE_CAMERA).sendToTarget()
    }


    private fun initPermission() {
        PermissionX.request(
            this,
            Manifest.permission.CAMERA,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            callback = { success, refuseList ->
                if (!success) {
                    Toast.makeText(this, "您拒绝了应用使用相机", Toast.LENGTH_SHORT).show()
                    this.finish()
                }
            })

    }
}